﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CameraUC
{
    /// <summary>
    /// Select camera button control
    /// </summary>
    /// <remarks>trungpv@vnext.vn</remarks>
    public partial class Camera : UserControl
    {
        #region Attributs and Getter/Setter
        private FVIL.Forms.CFviImageView m_imageView;
        private bool m_startCamera;
        private List<FVIL.DS.CFviFilterInfo> m_listCamera;
        private string m_cameraIniPath;
        private bool m_isSelectCamera;
        private int m_cameraDelay;
        public EventHandler eventPlay; 
        public EventHandler eventPause;

        #endregion

        public Camera()
        {
            InitializeComponent();
        }

        #region Logic functions
        /// <summary>
        /// Initialize parameters
        /// </summary>
        /// <param name="imageView"></param>
        /// <param name="cameraIniPath"></param>
        public void setImageView(FVIL.Forms.CFviImageView imageView, string cameraIniPath, int cameraDelay)
        {
            m_startCamera = false;
            m_isSelectCamera = false;
            m_cameraDelay = cameraDelay;
            m_cameraIniPath = cameraIniPath;
            m_imageView = imageView;
            m_imageView.Refresh();
        }

        /// <summary>
        /// Check list connecting camera to computer
        /// </summary>
        /// <returns></returns>
        private bool checkListCamera()
        {
            m_listCamera = new List<FVIL.DS.CFviFilterInfo>();
            try
            {
                m_listCamera = FVIL.DS.SelectCameraForm.GetFilterList();
            }
            catch (Exception)
            {
                MessageBox.Show("カメラを接続してください。", "警報", MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
                return false; // if there isn't anny connecting camera
            }
            return true;
        }

        /// <summary>
        /// Change interface and status of camera button
        /// </summary>
        private void changeCameraStatus()
        {
            m_startCamera = !m_startCamera;
            btnCamera.Image = m_startCamera ? Properties.Resources.camera_pause :
                Properties.Resources.camera_play;
            btnCamera.Text = m_startCamera ? "カメラ停止" : "カメラ開始";
            btnCamera.Refresh();
        }

        /// <summary>
        /// Select one in list camera
        /// </summary>
        private void selectCamera()
        {
            // 1 camera connecting
            if (m_listCamera.Count == 1)
            {
                m_isSelectCamera = true;
                FVIL.DS.CFviGrabberParam param = new FVIL.DS.CFviGrabberParam();
                param.FilterInfo = m_listCamera[0];
                param.Save(m_cameraIniPath);
            }
            else if (!m_isSelectCamera)// in the case of multi camera connecting
            {
                SelectCameraForm cameraForm = new SelectCameraForm(m_listCamera, m_cameraIniPath);
                cameraForm.eventCancel += new EventHandler(OnCancelCamera);
                cameraForm.eventSelect += new EventHandler(OnSelectCamera);
                cameraForm.ShowDialog();
            }
        }

        /// <summary>
        /// Initialize camera from init file
        /// </summary>
        public void initCamera()
        {
            FVIL.DS.CFviGrabberParam loadparam = new FVIL.DS.CFviGrabberParam();
            try
            {
                loadparam.Load(m_cameraIniPath);
                cFviGrabberCamera.Controller.Create(loadparam);
                cFviGrabberCamera.Controller.ImageType = FVIL.ImageType.UC8;
                for (int index = 0; index < 3; index++)
                    cFviGrabberCamera.Controller.Images.Add(new FVIL.Data.CFviImage());
                cFviGrabberCamera.Controller.Validate();
            }
            catch
            {
                MessageBox.Show("カメラを接続してください。", "警報", MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
            }
        }

        /// <summary>
        /// Run camera
        /// </summary>
        private void startCamera()
        {
            cFviGrabberCamera.Controller.Run();
        }

        /// <summary>
        /// Pause camera
        /// </summary>
        private void stopCamera()
        {
            cFviGrabberCamera.Controller.Pause();
        }

        /// <summary>
        /// Release camera
        /// </summary>
        public void releaseCamera()
        {
            cFviGrabberCamera.Controller.Stop();
            cFviGrabberCamera.Controller.Release();
        }
        #endregion

        #region Events on form
        private void btnCamera_Click(object sender, EventArgs e)
        {
            // Select camera for first time
            if (!m_isSelectCamera)
            {
                if (!checkListCamera()) return;
                selectCamera();
                if (!m_isSelectCamera) return; // if not select camera in SelectCameraForm
                initCamera();
            }
            // Run camera
            if (!m_startCamera)
            {
                startCamera();
                OnPlayCamera();
            }
            else
            {
                stopCamera();
                OnPauseCamera();
            }
            changeCameraStatus();
        }

        /// <summary>
        /// Get frame image to display
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cFviGrabberCamera_FrameValid(object sender, FVIL.DS.GrabberEventArgs e)
        {
            if (e.Status == FVIL.DS.GrabberEventStatus.Done)
            {
                try
                {
                    System.Threading.Thread.Sleep(m_cameraDelay);
                    m_imageView.Image = e.Image;
                    m_imageView.Refresh();
                }
                catch
                {
                    return;
                }
            }
        }

        /// <summary>
        /// Event rises when no camera is selected from list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void OnCancelCamera(object sender, EventArgs e)
        {
            m_isSelectCamera = false;
        }

        /// <summary>
        /// Event rises when one camera is selected from list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void OnSelectCamera(object sender, EventArgs e)
        {
            m_isSelectCamera = true;
        }

        /// <summary>
        /// Event rises when press camera 'Play' button
        /// </summary>
        public virtual void OnPlayCamera()
        {
            EventHandler handler = eventPlay;
            if (handler != null)
            {
                handler(null, EventArgs.Empty);
            }
        }

        /// <summary>
        /// Event rises when press camera 'Pause' button
        /// </summary>
        public virtual void OnPauseCamera()
        {
            EventHandler handler = eventPause;
            if (handler != null)
            {
                handler(null, EventArgs.Empty);
            }
        }
        #endregion


    }
}
